%% @author Mochi Media <dev@mochimedia.com>
%% @copyright 2010 Mochi Media <dev@mochimedia.com>

%% @doc Web server for testweb.

-module(gameweb_web).
-author("Mochi Media <dev@mochimedia.com>").

-export([start/1, stop/0, loop/3]).
-export([ok/2, set_close/0]).

%% External API

start(Options) ->
    {DocRoot, Options1} = get_option(docroot, Options),
    {HandleMod, Options2} = get_option(handle_mod, Options1),
    Loop = fun (Req) ->
            ?MODULE:loop(Req, DocRoot, HandleMod)
    end,
    mochiweb_http:start([{name, ?MODULE}, {loop, Loop} | Options2]).

stop() ->
    mochiweb_http:stop(?MODULE).

%% @doc 设置强制关闭连接结束
set_close() ->
    put(mochiweb_request_force_close, true),
    ok.

%% @doc 返回响应
ok(Req, Response) ->
    set_close(), %% 默认关闭
    Req:ok({"text/plain; charset=UTF8", _Headers = [], Response}).

%% 处理逻辑
loop(Req, _DocRoot, HandleMod) ->
    %% DocRoot : d:/game/qztx2/gameserver/priv/www
    %% Req:serve_file(Path, _DocRoot);
    %% http://xxx/index.html  ==> xxx/priv/www/index.html
    "/" ++ Path = Req:get(path),
    set_close(), %% 默认关闭
    try
        case Req:get(method) of
            Method when Method =:= 'HEAD' ->
                Req:not_found();
            Method when Method =:= 'GET' orelse Method =:= 'POST' ->
                apply(gameweb_handle, do, [Path, Method, Req, HandleMod]);
            _ ->
                Req:respond({501, [], []})
        end
    catch
        Type:What ->
            Report = ["web request failed",
                      {path, Path},
                      {type, Type}, {what, What},
                      {trace, erlang:process_info(self(), current_stacktrace)}],
            error_logger:error_report(Report),
            %% NOTE: mustache templates need \ because they are not awesome.
            Req:respond({500, [{"Content-Type", "text/plain"}], "request failed, sorry\n"})
    end.

%% Internal API

get_option(Option, Options) ->
    {proplists:get_value(Option, Options), proplists:delete(Option, Options)}.

%%
%% Tests
%%
-ifdef(TEST).
-include_lib("eunit/include/eunit.hrl").

you_should_write_a_test() ->
    ?assertEqual(
       "No, but I will!",
       "Have you written any tests?"),
    ok.

-endif.
